package org.jawa.exam.question;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jawa.admin.util.Page;
import org.jawa.core.cache.Cache;
import org.jawa.core.cache.CacheFactory;
import org.jawa.core.database.DbConnectionManager;
import org.jawa.core.exception.NotFoundException;
import org.jawa.exam.model.Question;
import org.jawa.exam.model.QuestionOption;
import org.jawa.exam.model.QuestionSort;
import org.jawa.jdbc.JdbcUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QuestionManager {
	private static final Logger Log = LoggerFactory.getLogger(QuestionManager.class);

	/**
	 * 根据试题类型查询的SQL.
	 */
	private static final String QUESTION_COUNT = "SELECT count(*) FROM QUESTION WHERE question_type=?";

	// 试题缓存
	private Cache<Long, Question> questionCache;

	// 试题分类缓存
	private Cache<Long, QuestionSort> questionSortCache;

	// 单一实例.
	private static class QuestionManagerContainer {
		private static QuestionManager instance = new QuestionManager();
	}

	public static QuestionManager getInstance() {
		return QuestionManagerContainer.instance;
	}

	private QuestionManager() {
		questionCache = CacheFactory.createCache("question");
		questionCache = CacheFactory.createCache("questionSort");
	}

	/**
	 * 创建试题信息.
	 * 
	 * @param Question
	 *            试题信息.
	 * @return 创建好的试题信息实例.
	 * @throws Exception
	 *             创建试题信息异常.
	 */
	public Question createQuestion(Question question, List<QuestionOption> questionOptions) throws Exception {
		Connection con = null;
		boolean abortTransaction = false;
		try {
			con = DbConnectionManager.getTransactionConnection();
			for (Iterator iterator = questionOptions.iterator(); iterator.hasNext();) {
				QuestionOption questionOption = (QuestionOption) iterator.next();
				JdbcUtils.insertTableFromBean(con, "QUESTION_OPTION", questionOption, "CachedSize");
			}
			JdbcUtils.insertTableFromBean(con, "QUESTION", question, "CachedSize");
		} catch (Exception e) {
			abortTransaction = true;
			Log.error("将试题存入数据库时发生错误!", e);
			throw e;
		} finally {
			DbConnectionManager.closeTransactionConnection(con, abortTransaction);
		}
		questionCache.put(question.getQuestionId(), question);
		return question;
	}

	/**
	 * 根据查询条件返回系统中的试题.
	 * 
	 * @param startIndex
	 * @param numResults
	 * @return
	 * @throws
	 */
	public List<Question> getQuestions(Page page) {
		List questions = new ArrayList();
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM QUESTION WHERE 1=1 ");
		try {
			questions = JdbcUtils.queryToBeanList(Question.class, sql.toString());
			page.setTotalCount(JdbcUtils.countSqlRowNumber(sql.toString()));
		} catch (SQLException e) {
			Log.error("查询试卷信息时发生错误!", e);
		}
		return questions;
	}

	/**
	 * 根据查询条件返回系统中试题选项.
	 * 
	 * @param startIndex
	 * @param numResults
	 * @return
	 * @throws
	 */
	public List<QuestionOption> getQuestionOptions(Long questionId) {
		List questions = new ArrayList();
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM QUESTION_OPTION WHERE 1=1 AND QUESTIONID = ? ");
		try {
			questions = JdbcUtils.queryToBeanList(QuestionOption.class, sql.toString(), questionId);
		} catch (SQLException e) {
			Log.error("查询试题选项信息时发生错误!", e);
		}
		return questions;
	}

	/**
	 * 返回指定 brId 的部门.
	 * 
	 * @param userId
	 *            部门的 brId .
	 * @return br_Id 等于 <tt>brId</tt> 的部门.
	 * @throws NotFoundException
	 *             部门没有找到.
	 */
	public Question getQuestion(Long questionId) throws NotFoundException {
		if (questionId == null) {
			throw new NotFoundException("questionId cannot be null");
		}

		Question question = questionCache.get(questionId);
		if (question == null) {
			synchronized (questionCache) {
				question = questionCache.get(questionId);
				if (question == null) {
					question = loadQuestionById(questionId);
					// 放入部门缓存
					questionCache.put(questionId, question);
				}
			}
		}
		return question;
	}

	/**
	 * 根据 questionId从数据库加载试题。
	 * 
	 * @param questionId
	 *            questionId
	 * @return 试题.
	 * 
	 * @throws 假如试题没有找到抛出
	 *             NotFoundException.
	 * 
	 */
	public Question loadQuestionById(Long questionId) throws NotFoundException {
		Question question = null;
		try {
			question = JdbcUtils
					.queryToBean(Question.class, "SELECT * FROM QUESTION WHERE questionId = ? ", questionId);
			return question;
		} catch (Exception e) {
			Log.error("查询部门信息时出错", e);
			throw new NotFoundException();
		}
	}

	/**
	 * 返回所有的试题分类
	 * 
	 * @Title: QuestionManager
	 * @Description: TODO
	 * @param @return
	 * @throws
	 */
	public List<QuestionSort> getQuestionSorts() {
		List sorts = new ArrayList();
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM QUESTIONSORT WHERE 1=1 ");
		try {
			sorts = JdbcUtils.queryToBeanList(QuestionSort.class, sql.toString());
		} catch (SQLException e) {
			Log.error("查询试题分类信息时发生错误!", e);
		}

		return sorts;
	}

	/**
	 * 返回指定的试题分类.
	 * 
	 * @param questionSortId
	 *            试题分类编码 .
	 * @return 试题分类.
	 * @throws NotFoundException
	 *             没有找到.
	 */
	public QuestionSort getQuestionSort(Long questionSortId) throws NotFoundException {
		if (questionSortId == null) {
			throw new NotFoundException("questionSortId cannot be null");
		}

		QuestionSort questionSort = questionSortCache.get(questionSortId);
		if (questionSort == null) {
			synchronized (questionSortCache) {
				questionSort = questionSortCache.get(questionSortId);
				if (questionSort == null) {
					questionSort = loadQuestionSortById(questionSortId);
					// 放入部门缓存
					questionSortCache.put(questionSortId, questionSort);
				}
			}
		}
		return questionSort;
	}

	/**
	 * 根据 questionSortId从数据库加载试题分类。
	 * 
	 * @param questionId
	 *            questionId
	 * @return 试题分类编码.
	 * 
	 * @throws 假如没有找到抛出
	 *             NotFoundException.
	 * 
	 */
	private QuestionSort loadQuestionSortById(Long questionSortId) throws NotFoundException {
		QuestionSort questionSort = null;
		try {
			questionSort = JdbcUtils.queryToBean(QuestionSort.class, "SELECT * FROM QUESTIONSORT WHERE sortId = ? ",
					questionSortId);
			return questionSort;
		} catch (Exception e) {
			Log.error("查询试题分类时出错", e);
			throw new NotFoundException();
		}
	}

	/**
	 * 根据试题类型获取当前类型下试题总数
	 * 
	 * @param papaerType
	 *            试题类型
	 * @return 返回该类型下试题总数
	 */
	public int getQuestionCount(String questionType) {
		int count = 0;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = DbConnectionManager.getConnection();
			pstmt = con.prepareStatement(QUESTION_COUNT);
			pstmt.setString(0, questionType);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (SQLException e) {
			Log.error("获取试题信息总数出错！", e);
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return count;
	}

}
